package com.cskaoyan.javase.oop3._5lambda._3notice;

/**
 * 复习Lambda表达式的语法:
 * () -> {}
 * ()是重写方法的形参列表
 * {}是重写方法的重写方法体
 *
 * 方法引用:
 *      lambda表达式的本质就是把一个方法实现作为一个对象
 *      那么lambda表达式指向的方法实现,可以是一个已经存在的方法
 *      (形参列表) -> 已存在的方法(形参列表);
 *      同类中的静态方法可以直接写方法名,同类中的成员方法需要对象名点
 *      不同类,静态方法要加上类名,成员方法需要创建那个类的对象
 *
 *      更简化的形式,语法:
 *      方法的归属者::方法名;
 *
 *
 * 注意事项:
 *      1.方法引用指向已存在的方法,不仅可以是自己手写的方法,还可以是jdk源码或者三方工具包中存在的方法.
 *
 *      2.Lambda表达式方法引用指向的已实现方法,返回值类型可以允许和抽象方法的返回值类型保持不一致.
 *      a.基本数据类型和void保持一致
 * 	    b.引用数据类型,抽象方法是父类类型,已实现的这个子类方法可以返回子类类型
 *
 * 	    3.Lambda表达式访问作用域内部的局部变量,那么这个局部变量应该是一个常量.
 *
 * 	    4.Lambda表达式和局部内部类,匿名内部类稍有不同的地方在于,Lambda表达式的大括号没有自己的作用域,和装有Lambda表达式的局部位置共用一个作用域.
 *
 * @since 09:36
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {

        IA ia = a -> a + "hello world!";
        System.out.println(ia.test(100));

        IA ia2 = a -> myTest(a);
        System.out.println(ia2.test(111));

        System.out.println("---------------");

        IA ia3 = Demo::myTest;
        ia3.test(100);
        System.out.println("--------------");

        IB ib = System.out::println;
        ib.test("我是一个聪明的人!");

        System.out.println("------------------");
        IC ic = new Demo()::myTest;

        int a = 10;
        ITest it = () -> {
            System.out.println(a);
            // System.out.println(a++);
            // Variable 'a' is already defined in the scope
            // int a = 10;
        };

        // 匿名内部类实现
        new ITest() {
            int a = 10;

            @Override
            public void test() {
                int a = 10;
            }
        };


    }

    public static String myTest(int num) {
        System.out.println("hello world!");
        System.out.println("66666");
        return "777";
    }

    public Son myTest() {
        return new Son();
    }
}

@FunctionalInterface
interface ITest {
    void test();
}

@FunctionalInterface
interface IA {
    String test(int a);
}

@FunctionalInterface
interface IB {
    void test(String s);
}

@FunctionalInterface
interface IC {
    Father test();
}


class Father {
}

class Son extends Father {
}